package cn.com.oidreams.aliyun.robot.service;

import cn.com.oidreams.aliyun.robot.entity.BaseRequest;
import cn.com.oidreams.common.utils.ReflectUtil;
import cn.com.oidreams.common.dto.RobotResponse;
import cn.com.oidreams.common.enums.AlgorithmEnum;
import cn.com.oidreams.common.enums.EncodingEnum;
import cn.com.oidreams.common.enums.ExceptionCode;
import cn.hutool.core.codec.Base64;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;

/***
 ** @category 请用一句话描述这个类的用途
 ** @author qing.yunhui
 ** @email: qingyh@glodon.com
 ** @createTime: 2021-11-25 16:23
 **/
public abstract class AbsDingTalkMessage {

    /**
     * <p>处理请求(子类需要根据不同场景实现)</p>
     * @param request
     * @return
     * */
    public abstract <T> String handle(BaseRequest<T> request);

    /**
     * <p>处理请求</p>
     * @param request
     * @return
     * */
    public <T> RobotResponse doHandle(BaseRequest<T> request) throws Exception {
        boolean pass = ReflectUtil.isRequiredPass(request);
        if(!pass){return new RobotResponse(ExceptionCode.VERIFICATION_FAILED);}
        String result = handle(request);
        return JSONUtil.toBean(new JSONObject(result), RobotResponse.class);
    }
    /**
     * <p>加签(把timestamp+"\n"+secret当做签名字符串，使用HmacSHA256算法计算签名，然后进行Base64 encode，最后再把签名参数再进行urlEncode，得到最终的签名（需要使用UTF-8字符集）)</p>
     * @param timestamp
     * @param secret
     * @return
     * */
    protected static String getSign(long timestamp,String secret) throws Exception {
        String stringToSign = String.format("%s\n%s",timestamp,secret);
        Mac mac = Mac.getInstance(AlgorithmEnum.HmacSHA256.getCode());
        mac.init(new SecretKeySpec(secret.getBytes(EncodingEnum.UTF_8.getCode()), AlgorithmEnum.HmacSHA256.getCode()));
        byte[] signData = mac.doFinal(stringToSign.getBytes(EncodingEnum.UTF_8.getCode()));
        return URLEncoder.encode(Base64.encode(signData),EncodingEnum.UTF_8.getCode());
    }

    /**
     * <p>发送消息</p>
     * @param request 待发送的消息
     * @return
     * */
    protected static <T> String send(BaseRequest<T> request){
        try {
            long timestamp = System.currentTimeMillis();
            String sign = getSign(timestamp,request.getSecret());
            //钉钉机器人地址（配置机器人的webhook）
            String params = String.format("?access_token=%s&timestamp=%s&sign=%s",new Object[]{request.getAccessToken(),timestamp,sign});
            String dingUrl = String.format("https://oapi.dingtalk.com/robot/send%s",params);
            //推送消息（http请求）
            return HttpUtil.post(dingUrl, JSONUtil.toJsonStr(request));
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
}
